<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>五子棋</title>
		<style>
			canvas {
				display: block;
				margin: 0 auto;
				background-color: rgb(204, 195, 112);
			}
		</style>
	</head>
	<body>
		<canvas id="canvas" width="800" height="800"></canvas>
		<script>
			let canvas = document.getElementById("canvas");
			let context = canvas.getContext("2d");

			let board = [];
			let color = "black";

			initGame();
			canvas.addEventListener("click", (e) => {
				// 解构
				let {
					offsetX,
					offsetY
				} = e;

				// 棋盘索引位置
				let i = Math.floor((offsetX + 25) / 50);
				let j = Math.floor((offsetY + 25) / 50);

				// 合法检查
				if (outOfBound(offsetX, offsetY) || exist(i, j)) {
					return;
				}

				// 绘制棋子
				drawPiece(i, j);

				// 是否获胜
				if (won()) {
					setTimeout(() => {
						alert(`${color === "white" ? "黑" : "白"}棋获胜，请刷新重开`);
					}, 50);
				}

				// 改变颜色
				changeColor();
			});

			function initGame() {
				for (let i = 1; i <= 15; i++) {
					context.moveTo(50, 50 * i);
					context.lineTo(750, 50 * i);
					context.stroke();

					context.moveTo(50 * i, 50);
					context.lineTo(50 * i, 750);
					context.stroke();

					board[i] = [];
				}
			}

			function outOfBound(x, y) {
				if (x < 25 || y < 25 || x > 775 || y > 775) {
					return true;
				}
				return false;
			}

			function exist(i, j) {
				if (board[i][j]) {
					return true;
				}
				return false;
			}

			function drawPiece(i, j) {
				doDraw(i * 50, j * 50);
				savePiece(i, j);
			}

			function doDraw(x, y) {
				context.beginPath();
				context.arc(x, y, 23, 0, 2 * Math.PI);

				let g = context.createRadialGradient(x, y, 0, x, y, 20);
				g.addColorStop(0, color === "black" ? "#ccc" : "#666");
				g.addColorStop(1, color === "black" ? "#000" : "#fff");
				context.fillStyle = g;
				context.fill();
				context.closePath();
			}

			function savePiece(i, j) {
				board[i][j] = color;
			}

			function changeColor() {
				color = color === "black" ? "white" : "black";
			}

			function won() {
				for (let i = 1; i <= 15; i++) {
					for (let j = 1; j <= 15; j++) {
						// 水平
						if (
							i <= 11 &&
							board[i][j] === color &&
							board[i + 1][j] === color &&
							board[i + 2][j] === color &&
							board[i + 3][j] === color &&
							board[i + 4][j] === color
						) {
							return true;
						}
						// 垂直
						if (
							j <= 11 &&
							board[i][j] === color &&
							board[i][j + 1] === color &&
							board[i][j + 2] === color &&
							board[i][j + 3] === color &&
							board[i][j + 4] === color
						) {
							return true;
						}
						// 右下
						if (
							i <= 11 &&
							j <= 11 &&
							board[i][j] === color &&
							board[i + 1][j + 1] === color &&
							board[i + 2][j + 2] === color &&
							board[i + 3][j + 3] === color &&
							board[i + 4][j + 4] === color
						) {
							return true;
						}
						// 左下
						if (
							i >= 5 &&
							j <= 11 &&
							board[i][j] === color &&
							board[i - 1][j + 1] === color &&
							board[i - 2][j + 2] === color &&
							board[i - 3][j + 3] === color &&
							board[i - 4][j + 4] === color
						) {
							return true;
						}
					}
				}

				return false;
			}
		</script>
	</body>
</html>